<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="theme-color" content="#0b1220" />
    <title>Pydoll - scraping, the easier way</title>
    <meta name="description" content="Pydoll is a Python browser automation library built on CDP with zero configuration, async performance, intuitive API, and full type safety. Simple, powerful web automation." />
    <meta name="keywords" content="pydoll, browser automation, web automation, web scraping, scraping, data scraping, data extraction, crawler, crawling, headless browser, headless chrome, chrome devtools protocol, devtools protocol, cdp, python cdp, chrome cdp, async python, asyncio, network interception, request interception, browser context requests, http requests browser context, humanized interactions, human-like interactions, automation library, scraping framework, type safety, zero configuration, concurrent automation, browser preferences, downloads, python automation, modern web scraping" />
    <meta name="robots" content="index,follow" />
    <link rel="canonical" href="https://pydoll.tech/" />

    <!-- Open Graph -->
    <meta property="og:title" content="Pydoll - scraping, the easier way" />
    <meta property="og:description" content="Python browser automation with zero configuration, async performance, intuitive API, and full type safety. Simple, powerful web automation." />
    <meta property="og:type" content="website" />
    <meta property="og:image" content="https://pydoll.tech/images/logo.png" />
    <meta property="og:url" content="https://pydoll.tech/" />
    <meta property="og:site_name" content="Pydoll" />
    <meta property="og:locale" content="en_US" />
    <meta property="og:locale:alternate" content="pt_BR" />

    <!-- Twitter Card -->
    <meta name="twitter:card" content="summary_large_image" />
    <meta name="twitter:title" content="Pydoll - scraping, the easier way" />
    <meta name="twitter:description" content="Python browser automation with zero configuration, async performance, intuitive API, and full type safety." />
    <meta name="twitter:image" content="https://pydoll.tech/images/logo.png" />

    <!-- Performance hints -->
    <link rel="preconnect" href="https://cdn.tailwindcss.com" />
    <link rel="preconnect" href="https://cdn.jsdelivr.net" />
    <link rel="preconnect" href="https://pydoll.tech/" />

    <!-- Favicon -->
    <link rel="icon" type="image/png" href="/images/favicon.png" sizes="48x48 32x32 16x16" />
    <link rel="shortcut icon" type="image/png" href="/images/favicon.png" />
    <link rel="apple-touch-icon" href="/images/favicon.png" />

    <!-- Tailwind CSS via CDN -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- Schema.org: SoftwareApplication / SoftwareSourceCode -->
    <script type="application/ld+json">
      {
        "@context": "https://schema.org",
        "@graph": [
          {
            "@type": "Organization",
            "@id": "https://pydoll.tech/#org",
            "name": "Pydoll",
            "url": "https://pydoll.tech/",
            "logo": {
              "@type": "ImageObject",
              "url": "https://pydoll.tech/images/logo.png"
            },
            "sameAs": [
              "https://pypi.org/project/pydoll-python/"
            ]
          },
          {
            "@type": "WebSite",
            "@id": "https://pydoll.tech/#website",
            "name": "Pydoll",
            "url": "https://pydoll.tech/",
            "publisher": { "@id": "https://pydoll.tech/#org" },
            "inLanguage": "en",
            "potentialAction": {
              "@type": "SearchAction",
              "target": "https://pydoll.tech/docs/search/?q={search_term_string}",
              "query-input": "required name=search_term_string"
            }
          },
          {
            "@type": "WebPage",
            "@id": "https://pydoll.tech/#webpage",
            "url": "https://pydoll.tech/",
            "name": "Pydoll - scraping, the easier way",
            "isPartOf": { "@id": "https://pydoll.tech/#website" },
            "about": { "@id": "https://pydoll.tech/#software" },
            "description": "Pydoll is a Python CDP browser automation library for web scraping, with zero configuration, async performance, and intuitive API."
          },
          {
            "@type": "SoftwareApplication",
            "@id": "https://pydoll.tech/#software",
            "name": "Pydoll",
            "applicationCategory": "DeveloperApplication",
            "operatingSystem": "Windows, macOS, Linux",
            "programmingLanguage": "Python",
            "url": "https://pydoll.tech/",
            "image": "https://pydoll.tech/images/logo.png",
            "description": "Python library for browser automation via Chrome DevTools Protocol (CDP), with zero configuration, async performance, intuitive API, and full type safety.",
            "publisher": { "@id": "https://pydoll.tech/#org" },
            "offers": {
              "@type": "Offer",
              "price": 0,
              "priceCurrency": "USD"
            },
            "codeRepository": "https://github.com/autoscrape-labs/pydoll",
            "sameAs": [
              "https://pypi.org/project/pydoll-python/"
            ],
            "keywords": [
              "Pydoll",
              "browser automation",
              "web scraping",
              "Chrome DevTools Protocol",
              "async Python",
              "type safety",
              "zero configuration",
              "concurrent automation"
            ],
            "mainEntityOfPage": {"@id":"https://pydoll.tech/#webpage"}
          },
          {
            "@type": "FAQPage",
            "@id": "https://pydoll.tech/#faq",
            "mainEntity": [
              {
                "@type": "Question",
                "name": "What is Pydoll and why doesn't it use WebDriver?",
                "acceptedAnswer": {
                  "@type": "Answer",
                  "text": "Pydoll is a Python library that controls the browser via the Chrome DevTools Protocol (CDP), eliminating WebDrivers. This reduces layers, improves reliability and gives direct access to page events, network interception and JavaScript execution in the real tab context."
                }
              },
              {
                "@type": "Question",
                "name": "What makes Pydoll's setup so simple compared to other automation tools?",
                "acceptedAnswer": {
                  "@type": "Answer",
                  "text": "Just 'pip install pydoll-python' and you're ready. No WebDriver downloads, no PATH configuration, no version matching issues. Pydoll connects directly to Chrome via CDP, eliminating the entire driver layer that causes most automation headaches."
                }
              }
            ]
          }
        ]
      }
      </script>
      
    <script>
      tailwind.config = {
        theme: {
          extend: {
            colors: {
              brand: {
                50: '#eef2ff',
                100: '#e0e7ff',
                200: '#c7d2fe',
                300: '#a5b4fc',
                400: '#818cf8',
                500: '#6366f1',
                600: '#4f46e5',
                700: '#4338ca',
                800: '#3730a3',
                900: '#312e81'
              }
            }
          }
        }
      }
    </script>
    <!-- Prism.js (syntax highlight) -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/themes/prism-twilight.min.css" />
    <style>
      /* Harmonize code block background with Tailwind bg-slate-950 */
      :root { --code-bg: #020617; }
      html { scroll-behavior: smooth; }
      /* Reveal on scroll */
      .reveal { opacity: 0; transform: translateY(12px); transition: opacity .6s ease, transform .6s ease; will-change: transform, opacity; }
      .revealed { opacity: 1; transform: none; }
      /* Tilt base */
      .tilt-card { transform-style: preserve-3d; transform: perspective(1000px); transition: transform .18s ease, box-shadow .18s ease; }
      .tilt-card:hover { transition: transform .06s ease; }
      pre[class*="language-"], code[class*="language-"] {
        background: var(--code-bg) !important;
        font-size: 13px !important;
        line-height: 1.5 !important;
      }
      pre[class*="language-"] { 
        border: 1px solid rgba(255,255,255,0.1); 
        border-radius: 8px;
        margin: 0;
        overflow-x: auto;
        overflow-y: hidden; /* avoid vertical scrollbar differences (Chrome vs Firefox) */
      }
      /* Remove inner padding from code so pre controls spacing */
      pre[class*="language-"] > code { 
        background: transparent !important; 
        padding: 0;
      }
      /* Ensure syntax highlighting works */
      .token.keyword { color: #c792ea !important; }
      .token.string { color: #c3e88d !important; }
      .token.function { color: #82aaff !important; }
      .token.comment { color: #546e7a !important; }
      .token.operator { color: #89ddff !important; }
      .token.punctuation { color: #89ddff !important; }
      .token.builtin { color: #ffcb6b !important; }
      .token.class-name { color: #ffcb6b !important; }
    </style>
  </head>
  <body class="bg-slate-950 text-slate-100 antialiased">
    <!-- Navbar -->
    <header class="sticky top-0 z-50 backdrop-blur supports-[backdrop-filter]:bg-slate-950/60">
      <div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
        <div class="flex h-16 items-center justify-between">
          <a href="/" class="flex items-center gap-3">
            <img src="https://pydoll.tech/images/logo.png" alt="Pydoll" class="h-8 w-auto" />
          </a>
          <!-- Desktop nav -->
          <nav class="hidden items-center gap-2 sm:flex sm:gap-3">
            <a href="https://pydoll.tech/docs/" class="px-3 py-2 text-sm font-medium text-slate-200 hover:text-white">Docs</a>
            <a href="#install" class="px-3 py-2 text-sm font-medium text-slate-200 hover:text-white">Install</a>
            <a href="#sponsors" class="px-3 py-2 text-sm font-medium text-slate-200 hover:text-white">Sponsors</a>
            <a href="#faq" class="px-3 py-2 text-sm font-medium text-slate-200 hover:text-white">FAQ</a>
            <a href="https://github.com/sponsors/thalissonvs" target="_blank" rel="noopener" class="px-3 py-2 text-sm font-medium text-slate-200 hover:text-white">Sponsor</a>
            <a href="https://github.com/autoscrape-labs/pydoll" target="_blank" rel="noopener" aria-label="Star on GitHub" class="inline-flex items-center gap-2 rounded-md bg-yellow-500 px-3 py-2 text-sm font-semibold text-slate-900 shadow hover:bg-yellow-400">
              <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15 9 22 9 17 14 19 22 12 18 5 22 7 14 2 9 9 9 12 2"/></svg>
              Star
              <span id="starCount" class="hidden rounded px-2 py-0.5 text-slate-900 sm:inline-block">...</span>
            </a>
          </nav>
          <!-- Mobile toggle -->
          <button id="mobileMenuButton" aria-controls="mobileMenu" aria-expanded="false" class="inline-flex items-center justify-center rounded-md p-2 text-slate-200 hover:text-white hover:bg-white/5 focus:outline-none focus:ring-2 focus:ring-brand-500 sm:hidden" type="button">
            <span class="sr-only">Open main menu</span>
            <svg id="iconMenu" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
            <svg id="iconClose" xmlns="http://www.w3.org/2000/svg" class="hidden h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
          </button>
        </div>
        <!-- Mobile menu panel -->
        <div id="mobileMenu" class="hidden sm:hidden">
          <div class="space-y-1 border-t border-white/10 py-3">
            <a href="https://pydoll.tech/docs/" class="block rounded-md px-3 py-2 text-sm font-medium text-slate-200 hover:bg-white/5">Docs</a>
            <a href="#install" class="block rounded-md px-3 py-2 text-sm font-medium text-slate-200 hover:bg-white/5">Install</a>
            <a href="#sponsors" class="block rounded-md px-3 py-2 text-sm font-medium text-slate-200 hover:bg-white/5">Sponsors</a>
            <a href="#faq" class="block rounded-md px-3 py-2 text-sm font-medium text-slate-200 hover:bg-white/5">FAQ</a>
            <a href="https://github.com/sponsors/thalissonvs" target="_blank" rel="noopener" class="block rounded-md px-3 py-2 text-sm font-medium text-slate-200 hover:bg-white/5">Sponsor</a>
            <a href="https://github.com/autoscrape-labs/pydoll" target="_blank" rel="noopener" class="mt-2 inline-flex w-full items-center justify-center gap-2 rounded-md bg-yellow-500 px-3 py-2 text-sm font-semibold text-slate-900 shadow hover:bg-yellow-400"><svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15 9 22 9 17 14 19 22 12 18 5 22 7 14 2 9 9 9 12 2"/></svg> Star</a>
          </div>
        </div>
      </div>
    </header>

    <!-- Hero -->
    <section id="hero" class="relative overflow-hidden">
      <div id="heroGradient" class="pointer-events-none absolute inset-0 -z-10 h-full bg-gradient-to-b from-indigo-600/30 via-fuchsia-600/10 to-transparent blur-3xl"></div>
      <div id="cursorGlow" aria-hidden="true" class="pointer-events-none absolute -z-10 hidden h-72 w-72 rounded-full bg-gradient-to-tr from-brand-500/25 via-fuchsia-500/15 to-transparent blur-3xl sm:block" style="left:0;top:0;"></div>
      <div class="mx-auto max-w-7xl px-4 pb-12 pt-16 sm:pb-16 sm:pt-24 lg:flex lg:items-start lg:gap-12 lg:px-8">
        <div class="mx-auto max-w-2xl lg:mx-0 lg:flex-auto">
          <h1 class="text-4xl font-bold tracking-tight sm:text-6xl">
            Pydoll: scraping, the easier way
          </h1>
          <p class="mt-6 text-lg leading-8 text-slate-300">
            Built from scratch with zero configuration complexity, Pydoll connects directly to the Chrome DevTools Protocol. 
            No WebDrivers, no setup headaches - just async performance, intuitive API, and full type safety.
          </p>
          <div class="mt-8 flex flex-col gap-3 sm:flex-row sm:items-center">
            <a href="https://github.com/autoscrape-labs/pydoll" target="_blank" rel="noopener" class="inline-flex items-center justify-center gap-2 rounded-md bg-yellow-500 px-5 py-3 text-base font-semibold text-slate-900 shadow hover:bg-yellow-400">
              <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15 9 22 9 17 14 19 22 12 18 5 22 7 14 2 9 9 9 12 2"/></svg>
              Star on GitHub
            </a>
            <a href="https://pydoll.tech/docs/" class="inline-flex items-center justify-center gap-2 rounded-md border border-white/10 px-5 py-3 text-base font-semibold text-white/90 hover:bg-white/5">
              📖 View Documentation
            </a>
            <a href="#install" class="inline-flex items-center justify-center gap-2 rounded-md bg-slate-800 px-5 py-3 text-base font-semibold text-white/90 hover:bg-slate-700">
              ⬇️ Install via pip
            </a>
          </div>
          
        </div>
        <div class="mt-12 w-full lg:mt-0 lg:max-w-xl lg:flex-none reveal">
          <div class="tilt-card relative overflow-hidden rounded-xl border border-white/10 bg-slate-900/40 p-6 shadow-xl">
            <div class="space-y-4">
              <div class="flex items-center gap-3">
              </div>
              <div class="rounded-lg bg-slate-950 p-0">
                <iframe 
                  class="w-full aspect-video rounded-lg" 
                  src="https://www.youtube.com/embed/sSw5dS3dQ8k" 
                  title="YouTube video player" 
                  frameborder="0" 
                  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
                  allowfullscreen>
                </iframe>
              </div>
              <div class="flex items-center justify-between text-xs text-slate-400">
                <span>✨ Simple, powerful, async</span>
                <span>🚀 Ready in seconds</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- Quick Intro / Features -->
    <section class="mx-auto max-w-7xl px-4 pt-10 pb-6 sm:px-6 lg:px-8">
      <div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
        <div id="cardZeroConfig" role="button" aria-controls="modalZeroConfig" class="reveal tilt-card cursor-pointer rounded-xl border border-white/10 bg-slate-900/40 p-6 transition-transform duration-200 hover:bg-white/5">
          <h3 class="flex items-center gap-2 text-lg font-semibold">
            <svg class="h-5 w-5 text-slate-300" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <circle cx="12" cy="12" r="9"></circle>
              <line x1="5" y1="5" x2="19" y2="19"></line>
            </svg>
            <span>Zero Configuration</span>
          </h3>
          <p class="mt-2 text-sm text-slate-300">Install and automate immediately. No drivers, no PATH variables, no setup hell.</p>
        </div>
        <div id="cardAsync" role="button" aria-controls="modalAsync" class="reveal tilt-card cursor-pointer rounded-xl border border-white/10 bg-slate-900/40 p-6 transition-transform duration-200 hover:bg-white/5">
          <h3 class="flex items-center gap-2 text-lg font-semibold">
            <svg class="h-5 w-5 text-slate-300" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <polyline points="8,7 4,12 8,17"></polyline>
              <polyline points="16,7 20,12 16,17"></polyline>
            </svg>
            <span>Async by Design</span>
          </h3>
          <p class="mt-2 text-sm text-slate-300">Built for concurrent automation with true async/await support from day one.</p>
        </div>
        <div id="cardTypeSafety" role="button" aria-controls="modalTypeSafety" class="reveal tilt-card cursor-pointer rounded-xl border border-white/10 bg-slate-900/40 p-6 transition-transform duration-200 hover:bg-white/5">
          <h3 class="flex items-center gap-2 text-lg font-semibold">
            <svg class="h-5 w-5 text-slate-300" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <path d="M9 12l2 2 4-4"></path>
              <path d="M21 12c0 4.97-4.03 9-9 9s-9-4.03-9-9 4.03-9 9-9c1.7 0 3.28.47 4.64 1.28"></path>
            </svg>
            <span>Full Type Safety</span>
          </h3>
          <p class="mt-2 text-sm text-slate-300">Complete type annotations. Your IDE knows exactly what each method returns.</p>
        </div>
        <div id="cardRequests" role="button" aria-controls="modalRequests" class="reveal tilt-card cursor-pointer rounded-xl border border-white/10 bg-slate-900/40 p-6 transition-transform duration-200 hover:bg-white/5">
          <h3 class="flex items-center gap-2 text-lg font-semibold">
            <svg class="h-5 w-5 text-slate-300" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <circle cx="12" cy="12" r="9"></circle>
              <ellipse cx="12" cy="12" rx="4" ry="9"></ellipse>
              <line x1="3" y1="12" x2="21" y2="12"></line>
            </svg>
            <span>Browser-context requests</span>
          </h3>
          <p class="mt-2 text-sm text-slate-300">Use <code>tab.request</code> to automatically inherit cookies, CORS and session state.</p>
        </div>
        <div id="cardIntuitive" role="button" aria-controls="modalIntuitive" class="reveal tilt-card cursor-pointer rounded-xl border border-white/10 bg-slate-900/40 p-6 transition-transform duration-200 hover:bg-white/5">
          <h3 class="flex items-center gap-2 text-lg font-semibold">
            <svg class="h-5 w-5 text-slate-300" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <line x1="12" y1="6" x2="12" y2="18"></line>
              <line x1="6" y1="12" x2="18" y2="12"></line>
              <circle cx="12" cy="12" r="1.5"></circle>
            </svg>
            <span>Intuitive API</span>
          </h3>
          <p class="mt-2 text-sm text-slate-300">Element finding feels like natural language. Simple, readable automation code.</p>
        </div>
        <div id="cardEvents" role="button" aria-controls="modalEvents" class="reveal tilt-card cursor-pointer rounded-xl border border-white/10 bg-slate-900/40 p-6 transition-transform duration-200 hover:bg-white/5">
          <h3 class="flex items-center gap-2 text-lg font-semibold">
            <svg class="h-5 w-5 text-slate-300" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
              <polyline points="3,12 8,12 10,8 12,16 14,12 21,12"></polyline>
            </svg>
            <span>Event-driven automation</span>
          </h3>
          <p class="mt-2 text-sm text-slate-300">React to page, network and runtime events in real-time.</p>
        </div>
      </div>
    </section>

    <!-- Feature Modals -->
    <div id="modalZeroConfig" class="fixed inset-0 z-[999] hidden items-center justify-center bg-black/70 p-4">
      <div class="relative w-full max-w-3xl rounded-xl border border-white/10 bg-slate-900 p-4 sm:p-6 shadow-2xl">
        <button id="closeZeroConfigModal" aria-label="Close" class="absolute right-3 top-3 rounded-full border border-white/10 bg-slate-800/80 p-1.5 text-slate-300 hover:bg-slate-700 hover:text-white">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
        </button>
        <div class="mb-3 flex items-center justify-between pr-10">
          <h4 class="text-lg font-semibold">Zero Configuration</h4>
        </div>
        <p class="mb-3 text-sm text-slate-300">Install and automate with a single command. No drivers, no PATH, no setup hell.</p>
        <pre id="zeroConfigCode" class="language-python overflow-x-auto rounded-lg border border-white/10 bg-slate-950 p-4"><code class="language-python">from pydoll.browser import Chrome

async def run():
    async with Chrome() as browser:
        tab = await browser.start()
        await tab.go_to('https://example.com')
</code></pre>
      </div>
    </div>

    <div id="modalAsync" class="fixed inset-0 z-[999] hidden items-center justify-center bg-black/70 p-4">
      <div class="relative w-full max-w-3xl rounded-xl border border-white/10 bg-slate-900 p-4 sm:p-6 shadow-2xl">
        <button id="closeAsyncModal" aria-label="Close" class="absolute right-3 top-3 rounded-full border border-white/10 bg-slate-800/80 p-1.5 text-slate-300 hover:bg-slate-700 hover:text-white">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
        </button>
        <div class="mb-3 flex items-center justify-between pr-10">
          <h4 class="text-lg font-semibold">Async by Design</h4>
        </div>
        <p class="mb-3 text-sm text-slate-300">Run multiple tabs concurrently with true async/await.</p>
        <pre id="asyncCode" class="language-python overflow-x-auto rounded-lg border border-white/10 bg-slate-950 p-4"><code class="language-python">import asyncio
from pydoll.browser import Chrome

async def scrape(url, tab):
    await tab.go_to(url)
    return await tab.execute_script('return document.title')

async def main():
    browser = Chrome()
    tab1 = await browser.start()
    tab2 = await browser.new_tab()
    titles = await asyncio.gather(
        scrape('https://google.com', tab1),
        scrape('https://github.com', tab2),
    )
    print(titles)
</code></pre>
      </div>
    </div>

    <div id="modalTypeSafety" class="fixed inset-0 z-[999] hidden items-center justify-center bg-black/70 p-4">
      <div class="relative w-full max-w-3xl rounded-xl border border-white/10 bg-slate-900 p-4 sm:p-6 shadow-2xl">
        <button id="closeTypeSafetyModal" aria-label="Close" class="absolute right-3 top-3 rounded-full border border-white/10 bg-slate-800/80 p-1.5 text-slate-300 hover:bg-slate-700 hover:text-white">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
        </button>
        <div class="mb-3 flex items-center justify-between pr-10">
          <h4 class="text-lg font-semibold">Full Type Safety</h4>
        </div>
        <p class="mb-3 text-sm text-slate-300">Your IDE knows exactly what each call returns.</p>
        <pre id="typeSafetyCode" class="language-python overflow-x-auto rounded-lg border border-white/10 bg-slate-950 p-4"><code class="language-python"># The IDE knows exactly what each call returns:
await tab.find(id='username')                 # → WebElement
await tab.find(id='username', find_all=True)  # → list[WebElement]
await tab.find(id='username', raise_exc=False)  # → WebElement | None
</code></pre>
      </div>
    </div>

    <div id="modalRequests" class="fixed inset-0 z-[999] hidden items-center justify-center bg-black/70 p-4">
      <div class="relative w-full max-w-3xl rounded-xl border border-white/10 bg-slate-900 p-4 sm:p-6 shadow-2xl">
        <button id="closeRequestsModal" aria-label="Close" class="absolute right-3 top-3 rounded-full border border-white/10 bg-slate-800/80 p-1.5 text-slate-300 hover:bg-slate-700 hover:text-white">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
        </button>
        <div class="mb-3 flex items-center justify-between pr-10">
          <h4 class="text-lg font-semibold">Browser-context requests</h4>
        </div>
        <p class="mb-3 text-sm text-slate-300">Perform HTTP in the same context as the tab: cookies, session and CORS are inherited automatically.</p>
        <pre id="requestsModalCode" class="language-python overflow-x-auto rounded-lg border border-white/10 bg-slate-950 p-4"><code class="language-python">await tab.go_to('https://app.example.com/login')
await (await tab.find(id='email')).type_text('user@example.com')
await (await tab.find(id='password')).type_text('secret')
await (await tab.find(type='submit')).click()

response = await tab.request.get('https://app.example.com/api/user/profile')
print(response.json())
</code></pre>
      </div>
    </div>

    <div id="modalIntuitive" class="fixed inset-0 z-[999] hidden items-center justify-center bg-black/70 p-4">
      <div class="relative w-full max-w-3xl rounded-xl border border-white/10 bg-slate-900 p-4 sm:p-6 shadow-2xl">
        <button id="closeIntuitiveModal" aria-label="Close" class="absolute right-3 top-3 rounded-full border border-white/10 bg-slate-800/80 p-1.5 text-slate-300 hover:bg-slate-700 hover:text-white">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
        </button>
        <div class="mb-3 flex items-center justify-between pr-10">
          <h4 class="text-lg font-semibold">Intuitive API</h4>
        </div>
        <p class="mb-3 text-sm text-slate-300">Readable element finding using attributes, CSS or XPath.</p>
        <pre id="intuitiveCode" class="language-python overflow-x-auto rounded-lg border border-white/10 bg-slate-950 p-4"><code class="language-python">button = await tab.find(tag_name='button', text='Submit', class_name='btn-primary')
await button.click()

el = await tab.query('div[data-testid="awesome-element"]')
</code></pre>
      </div>
    </div>

    <div id="modalEvents" class="fixed inset-0 z-[999] hidden items-center justify-center bg-black/70 p-4">
      <div class="relative w-full max-w-3xl rounded-xl border border-white/10 bg-slate-900 p-4 sm:p-6 shadow-2xl">
        <button id="closeEventsModal" aria-label="Close" class="absolute right-3 top-3 rounded-full border border-white/10 bg-slate-800/80 p-1.5 text-slate-300 hover:bg-slate-700 hover:text-white">
          <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
        </button>
        <div class="mb-3 flex items-center justify-between pr-10">
          <h4 class="text-lg font-semibold">Event-driven automation</h4>
        </div>
        <p class="mb-3 text-sm text-slate-300">React to page and network changes in real-time using the built-in event system.</p>
        <pre id="eventsCode" class="language-python overflow-x-auto rounded-lg border border-white/10 bg-slate-950 p-4"><code class="language-python"># Enable and listen to network events
await tab.enable_network_events()

async def on_response(params):
    info = params.get('response', {})
    print('status:', info.get('status'))

await tab.on('Network.responseReceived', on_response)
</code></pre>
      </div>
    </div>

    <!-- Stars Goal Section -->
    <section id="stars-goal" class="mx-auto max-w-7xl px-4 py-12 sm:px-6 lg:px-8">
      <div class="reveal rounded-xl border border-white/10 bg-slate-900/60 p-5 sm:p-6 transition-transform duration-200 hover:shadow-[0_10px_30px_rgba(99,102,241,0.15)]">
        <div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
          <div class="min-w-0">
            <h3 class="text-xl font-semibold">Help us reach 10k stars</h3>
            <p class="mt-1 text-sm text-slate-300">🚀 Your star means more features, more contributors, and a stronger community.</p>
            <div class="mt-4">
              <div class="flex items-center justify-between text-xs text-slate-400">
                <span id="starsProgressLabel">0 / 10,000</span>
                <span id="starsProgressPct">0%</span>
              </div>
              <div class="mt-2 h-2 w-full rounded-full bg-white/10 overflow-hidden">
                <div id="starsProgressBar" class="h-2 rounded-full bg-brand-500" style="width:0%"></div>
              </div>
            </div>
          </div>
          <div class="flex flex-col items-start sm:items-end gap-3">
            <div class="min-w-[220px]">
              <p class="text-xs font-medium text-slate-300">Latest stargazers</p>
              <ul id="stargazersList" class="mt-2 flex flex-wrap items-center gap-2">
                <!-- Filled via JS -->
              </ul>
            </div>
          </div>
        </div>
      </div>
    </section>
    <!-- Install CTA -->
    <section id="install" class="overflow-x-hidden">
      <div class="mx-auto max-w-7xl px-4 py-10 sm:px-6 lg:px-8">
        <div class="grid grid-cols-1 items-center gap-8 lg:grid-cols-2">
          <div class="min-w-0">
            <h2 class="text-2xl font-bold tracking-tight">Install and get started in seconds</h2>
            <p class="mt-3 text-slate-300">No complex setup. Install, import and automate.</p>
            <div class="mt-6 rounded-lg border border-white/10 bg-slate-950 p-3 sm:p-4">
              <div class="flex items-center gap-3 flex-wrap sm:flex-nowrap">
                <code id="installCmd" class="text-sm block max-w-full whitespace-nowrap overflow-x-auto">pip install pydoll-python</code>
                <button id="copyBtn" class="shrink-0 rounded-md bg-slate-800 px-3 py-1.5 text-xs font-semibold text-slate-100 hover:bg-slate-700">Copy</button>
              </div>
            </div>
            <!-- Quick code example -->
            <div class="mt-6">
              <p class="mb-2 text-sm text-slate-300">Quick example:</p>
              <pre class="language-python overflow-x-auto max-w-full rounded-lg border border-white/10 bg-slate-950 p-4"><code class="language-python">import asyncio
from pydoll.browser import Chrome

async def main():
    async with Chrome() as browser:
        tab = await browser.start()
        await tab.go_to('https://google.com')
        
        search_box = await tab.find(name='q')
        await search_box.type_text('Pydoll')
        await search_box.press_keyboard_key('Enter')

asyncio.run(main())
</code></pre>
            </div>
            <div class="mt-6 flex flex-wrap gap-3">
              <a href="https://pydoll.tech/docs/" target="_blank" rel="noopener" class="inline-flex items-center justify-center gap-2 rounded-md bg-white px-4 py-2 text-sm font-semibold text-slate-900 hover:bg-slate-200">Read the docs</a>
              <a href="https://github.com/sponsors/thalissonvs" target="_blank" rel="noopener" class="inline-flex items-center justify-center gap-2 rounded-md border border-white/10 px-4 py-2 text-sm font-semibold text-white/90 hover:bg-white/5">Support the project</a>
            </div>
          </div>
          <div class="reveal rounded-xl p-6 shadow-xl h-full flex flex-col justify-between">
            <div class="space-y-6">
              <div class="text-center space-y-4">
                <div class="mx-auto h-16 w-16 rounded-full bg-brand-500/10 flex items-center justify-center">
                  <svg class="h-8 w-8 text-brand-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <polyline points="8,7 4,12 8,17"></polyline>
                    <polyline points="16,7 20,12 16,17"></polyline>
                  </svg>
                </div>
                <h3 class="text-lg font-semibold text-slate-200">Zero to automation in seconds</h3>
                <p class="text-sm text-slate-300">Install once, automate forever.<br/>No drivers, no config, no headaches.</p>
              </div>
              
              <div class="space-y-4 border border-white/10 pt-4 p-4 rounded-lg">
                <div class="flex items-start gap-3">
                  <div class="h-2 w-2 rounded-full bg-green-400 mt-1.5"></div>
                  <div class="flex-1">
                    <h4 class="text-sm font-medium text-slate-200">Async by design</h4>
                    <p class="text-xs text-slate-400 mt-1">Built for concurrent automation with true async/await support</p>
                  </div>
                </div>
                <div class="flex items-start gap-3">
                  <div class="h-2 w-2 rounded-full bg-blue-400 mt-1.5"></div>
                  <div class="flex-1">
                    <h4 class="text-sm font-medium text-slate-200">Type safe</h4>
                    <p class="text-xs text-slate-400 mt-1">Complete type annotations - your IDE knows exactly what each method returns</p>
                  </div>
                </div>
                <div class="flex items-start gap-3">
                  <div class="h-2 w-2 rounded-full bg-purple-400 mt-1.5"></div>
                  <div class="flex-1">
                    <h4 class="text-sm font-medium text-slate-200">CDP direct</h4>
                    <p class="text-xs text-slate-400 mt-1">No WebDrivers, no compatibility issues - direct Chrome connection</p>
                  </div>
                </div>
                <div class="flex items-start gap-3">
                  <div class="h-2 w-2 rounded-full bg-yellow-400 mt-1.5"></div>
                  <div class="flex-1">
                    <h4 class="text-sm font-medium text-slate-200">Intuitive API</h4>
                    <p class="text-xs text-slate-400 mt-1">Element finding feels like natural language - simple and readable</p>
                  </div>
                </div>
              </div>
            </div>

          </div>
        </div>
      </div>
    </section>


    <!-- Sponsors -->
    <section id="sponsors" class="mx-auto max-w-7xl px-4 py-10 sm:px-6 lg:px-8">
      <div class="reveal rounded-xl border border-white/10 bg-slate-900/60 p-5 sm:p-6">
        <div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
          <div>
            <h2 class="text-2xl font-bold tracking-tight">Sponsors</h2>
            <p class="mt-1 text-sm text-slate-300">Companies and partners supporting Pydoll.</p>
          </div>
          <div>
            <a href="https://github.com/sponsors/thalissonvs" target="_blank" rel="noopener" class="inline-flex items-center gap-2 rounded-md bg-yellow-500 px-3 py-2 text-sm font-semibold text-slate-900 hover:bg-yellow-400">Become a sponsor</a>
          </div>
        </div>
        <ul id="sponsorsGrid" class="mt-6 grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3 sm:gap-4 items-center"></ul>
      </div>
    </section>


    <!-- FAQ (near footer) -->
    <section id="faq" class="mx-auto max-w-7xl px-4 pt-4 pb-10 sm:px-6 lg:px-8">
        <div class="mb-6">
          <h2 class="text-2xl font-bold tracking-tight">Frequently asked questions</h2>
          <p class="mt-1 text-sm text-slate-300">Top questions about Pydoll, its features and use cases.</p>
        </div>
        <div class="grid gap-3 sm:gap-4 ">
          <details class="group rounded-lg border border-white/10 bg-slate-900/40 p-4 hover:shadow-[0_10px_30px_rgba(99,102,241,0.15)]">
            <summary class="flex cursor-pointer list-none items-center gap-2 font-medium text-slate-200">
              <svg class="h-4 w-4 text-slate-400 group-open:rotate-90 transition-transform" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
              What is Pydoll and why doesn't it use WebDriver?
            </summary>
            <p class="mt-2 text-sm text-slate-300">Pydoll is a Python library that controls the browser via the <strong>Chrome DevTools Protocol (CDP)</strong>, eliminating WebDrivers. This reduces layers, improves reliability and gives direct access to advanced capabilities like page events, network interception and JavaScript execution in the real tab context.</p>
          </details>
          <details class="group rounded-lg border border-white/10 bg-slate-900/40 p-4 hover:shadow-[0_10px_30px_rgba(99,102,241,0.15)]">
            <summary class="flex cursor-pointer list-none items-center gap-2 font-medium text-slate-200">
              <svg class="h-4 w-4 text-slate-400 group-open:rotate-90 transition-transform" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
              How does Pydoll's type safety work in practice?
            </summary>
            <p class="mt-2 text-sm text-slate-300">Every method is fully typed with precise return annotations. Your IDE knows that <code>await tab.find(id='btn')</code> returns <code>WebElement</code>, <code>find_all=True</code> returns <code>list[WebElement]</code>, and <code>raise_exc=False</code> returns <code>WebElement | None</code>. This eliminates guesswork and catches errors before runtime.</p>
          </details>
          <details class="group rounded-lg border border-white/10 bg-slate-900/40 p-4 hover:shadow-[0_10px_30px_rgba(99,102,241,0.15)]">
            <summary class="flex cursor-pointer list-none items-center gap-2 font-medium text-slate-200">
              <svg class="h-4 w-4 text-slate-400 group-open:rotate-90 transition-transform" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
              What are “browser‑context requests” and when to use them?
            </summary>
            <p class="mt-2 text-sm text-slate-300">With <code>tab.request</code> you perform HTTP in the <strong>same context</strong> as the tab: cookies, session, headers and CORS are automatically inherited. Ideal for hybrid automation: log in via UI and then call the app's authenticated APIs with simplicity and speed.</p>
          </details>
          <details class="group rounded-lg border border-white/10 bg-slate-900/40 p-4 hover:shadow-[0_10px_30px_rgba(99,102,241,0.15)]">
            <summary class="flex cursor-pointer list-none items-center gap-2 font-medium text-slate-200">
              <svg class="h-4 w-4 text-slate-400 group-open:rotate-90 transition-transform" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
              What makes Pydoll's setup so simple compared to other tools?
            </summary>
            <p class="mt-2 text-sm text-slate-300">Just <code>pip install pydoll-python</code> and you're ready. No WebDriver downloads, no PATH configuration, no version matching hell. Pydoll connects directly to Chrome via CDP, eliminating the entire driver layer that causes most automation headaches.</p>
          </details>
          <details class="group rounded-lg border border-white/10 bg-slate-900/40 p-4 hover:shadow-[0_10px_30px_rgba(99,102,241,0.15)]">
            <summary class="flex cursor-pointer list-none items-center gap-2 font-medium text-slate-200">
              <svg class="h-4 w-4 text-slate-400 group-open:rotate-90 transition-transform" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
              How does concurrent automation work with multiple tabs?
            </summary>
            <p class="mt-2 text-sm text-slate-300">Pydoll is async-first, so you can run multiple tabs simultaneously with <code>asyncio.gather</code>. Create tabs with <code>await browser.new_tab()</code>, then process them in parallel. Each tab maintains its own session and state, giving you true concurrent automation without complexity.</p>
          </details>
        </div>
      </section>
    
    <!-- Final CTA (full width) -->
    <section class="mx-auto max-w-7xl px-4 pb-10 sm:px-6 lg:px-8">
      <div class="reveal rounded-xl border border-white/10 bg-slate-900/60 p-5 sm:p-6">
        <div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
          <div>
          <h4 class="text-lg font-semibold">Enjoying Pydoll?</h4>
          <p class="mt-1 text-sm text-slate-200/90">Star it, contribute to the repo or sponsor the development.</p>
          </div>
          <div class="flex flex-wrap gap-2">
            <a href="https://github.com/autoscrape-labs/pydoll" target="_blank" rel="noopener" class="inline-flex items-center gap-2 rounded-md bg-yellow-500 px-3 py-2 text-sm font-semibold text-slate-900 hover:bg-yellow-400">⭐ Star</a>
            <a href="https://github.com/autoscrape-labs/pydoll/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener" class="inline-flex items-center gap-2 rounded-md border border-white/10 px-3 py-2 text-sm font-semibold text-white/90 hover:bg-white/5">👩‍💻 Contribute</a>
            <a href="https://github.com/sponsors/thalissonvs" target="_blank" rel="noopener" class="inline-flex items-center gap-2 rounded-md bg-yellow-500 px-3 py-2 text-sm font-semibold text-slate-900 hover:bg-yellow-400">💖 Sponsor</a>
          </div>
        </div>
      </div>
    </section>

    <!-- Footer -->
    <footer class="border-t border-white/10">
      <div class="mx-auto max-w-7xl px-4 py-10 sm:px-6 lg:px-8">
        <div class="flex flex-col items-center justify-between gap-4 sm:flex-row">
          <div class="flex items-center gap-3">
            <img src="https://pydoll.tech/images/logo.png" alt="Pydoll" class="h-6 w-auto" />
            <p class="text-sm text-slate-400">Pydoll - making web automation simple and powerful</p>
          </div>
          <div class="flex items-center gap-3 text-sm text-slate-400">
            <a href="https://github.com/autoscrape-labs/pydoll" target="_blank" rel="noopener" class="hover:text-white">GitHub</a>
            <span aria-hidden="true">·</span>
            <a href="https://pydoll.tech/docs/" class="hover:text-white">Docs</a>
            <span aria-hidden="true">·</span>
            <a href="https://github.com/sponsors/thalissonvs" target="_blank" rel="noopener" class="hover:text-white">Sponsor</a>
          </div>
        </div>
      </div>
    </footer>

    <!-- JS -->
    <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-python.min.js"></script>
    <script>
      // Force Prism highlighting after DOM load
      document.addEventListener('DOMContentLoaded', function() {
        if (typeof Prism !== 'undefined') {
          Prism.highlightAll();
        }
      });
    </script>
    <script src="./script.js" defer></script>
  </body>
  </html>


